package androidvn.xenforo.fourums;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.http.NameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;

import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.RelativeLayout;
import androidvn.xenforo.fourums.R;
import androidvn.xenforo.fourums.ForumChildChildNodeFragment.setOnForumChildChildNodeClickListener;
import androidvn.xenforo.fourums.ForumChildNodeFragment.setOnForumChildNodeClickListener;
import androidvn.xenforo.fourums.ForumNodeFragment.setOnForumNodeClickListener;
import androidvn.xenforo.fourums.ThreadFragment.setOnThreadClickListener;
import androidvn.xenforo.fourums.adapter.CustomNodeListAdapter;
import androidvn.xenforo.fourums.adapter.ExpListAdapterLeft;
import androidvn.xenforo.fourums.model.NavDrawerItem;
import androidvn.xenforo.fourums.model.Node;
import androidvn.xenforo.fourums.widget.ConnectionDetector;
import androidvn.xenforo.fourums.widget.JsonParser;

public class MainActivity extends FragmentActivity implements
		setOnForumNodeClickListener, setOnThreadClickListener,
		setOnForumChildNodeClickListener, setOnForumChildChildNodeClickListener {
	ThreadFragment tf;
	PostFragment pf;
	String threadId, nodeId;

	private ConnectionDetector cd;
	//
	private DrawerLayout drawerLayout;
	private ActionBarDrawerToggle drawerToggle;
	// private ListView drawerList;
	private ExpandableListView drawerExpandableListLeft;
	private ListView drawerListRight;
	// nav drawer title
	// private CharSequence drawerTitle;
	// used to store app title
	private CharSequence title;
	// slide menu left items
	private String[] leftMenuTitle;
	private TypedArray leftMenuIcon;
	private String[] accountTitles;
	private TypedArray accountIcons;
	private String[] settingTitles;
	private TypedArray settingIcons;
	// left menu
	private ExpListAdapterLeft expListAdapterLeft;
	private ArrayList<NavDrawerItem> listParentDataLeft;
	private HashMap<NavDrawerItem, ArrayList<NavDrawerItem>> listChildDataLeft;
	// right menu
	private ArrayList<Node> nodeList, categoryList;

	private LayoutInflater inflater;
	private ProgressDialog pDialog;
	private JsonParser jsonParser = new JsonParser();

	private static final String URL = "http://android.vn/api.php?action=getNodes";
	// ALL JSON node names
	private static final String TAG_NODE_ID = "node_id";
	private static final String TAG_TITLE = "title";
	private static final String TAG_PARENT_NODE_ID = "parent_node_id";
	private static final String TAG_DISPLAY_ORDER = "display_order";
	private static final String TAG_DESCRIPTION = "description";
	private static final String TAG_DISPLAY_IN_LIST = "display_in_list";
	private static final String TAG_DEPTH = "depth";

	// admob
	private AdView adView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		cd = new ConnectionDetector(MainActivity.this);

		// admob
		// Create an ad.
		adView = new AdView(this, AdSize.BANNER, "a1519e300d97851");

		// disable editext focus
		this.getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		// action bar title
		title = getTitle();
		// creating drawer layout
		drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

		//RelativeLayout adLayout = (RelativeLayout) findViewById(R.id.relative_layout);

//		drawerLayout.addView(adView);
//		AdRequest adRequest = new AdRequest();
//		adRequest.addTestDevice(AdRequest.TEST_EMULATOR);
//		// Start loading the ad in the background.
//		adView.loadAd(adRequest);
		/*
		 * creating left menu
		 */

		drawerExpandableListLeft = (ExpandableListView) findViewById(R.id.expandable_list_left);
		inflater = getLayoutInflater();
		View header = inflater.inflate(R.layout.menu_list_header_layout, null);
		View footer = inflater.inflate(R.layout.menu_list_footer_layout, null);
		drawerExpandableListLeft.addHeaderView(header);
		drawerExpandableListLeft.addFooterView(footer);
		listParentDataLeft = new ArrayList<NavDrawerItem>();
		listChildDataLeft = new HashMap<NavDrawerItem, ArrayList<NavDrawerItem>>();
		leftMenuTitle = getResources().getStringArray(R.array.main_menu_titles);
		leftMenuIcon = getResources().obtainTypedArray(R.array.main_menu_icons);
		accountTitles = getResources().getStringArray(
				R.array.account_menu_titles);
		accountIcons = getResources().obtainTypedArray(
				R.array.account_menu_icons);
		settingTitles = getResources().getStringArray(
				R.array.setting_menu_titles);

		settingIcons = getResources().obtainTypedArray(
				R.array.setting_menu_icons);

		// check internet
		cd = new ConnectionDetector(getApplicationContext());
		Global.networkStatus = cd.isConnectingToInternet();
		if (Global.networkStatus) {
			// serverStatus = cd.isConnectedToServer(URL, 30000);
			// if (serverStatus) {

			setDataLeftMenu();
			// on group click listener
			drawerExpandableListLeft
					.setOnGroupClickListener(new OnGroupClickListener() {
						@Override
						public boolean onGroupClick(ExpandableListView parent,
								View v, int groupPosition, long id) {

							displayViewLeft(groupPosition);
							Log.d("group position",
									listParentDataLeft.get(groupPosition)
											.getTitle());
							if (Global.loginStatus == false
									&& groupPosition == 2) {
								return true;
							}
							return false;
						}
					});
			drawerExpandableListLeft
					.setOnChildClickListener(new OnChildClickListener() {
						@Override
						public boolean onChildClick(ExpandableListView parent,
								View v, int groupPosition, int childPosition,
								long id) {
							displayViewLeft(groupPosition, childPosition);
							Log.d("child position",
									listChildDataLeft
											.get(listParentDataLeft
													.get(groupPosition))
											.get(childPosition).getTitle());
							return false;
						}
					});
			drawerExpandableListLeft
					.setOnGroupExpandListener(new OnGroupExpandListener() {
						int previousGroup = -1;

						@Override
						public void onGroupExpand(int groupPosition) {
							if (groupPosition != previousGroup) {
								drawerExpandableListLeft
										.collapseGroup(previousGroup);
							}
							previousGroup = groupPosition;

						}
					});
			/*
			 * creating right menu
			 */
			drawerListRight = (ListView) findViewById(R.id.list_view_right);
			nodeList = new ArrayList<Node>();
			categoryList = new ArrayList<Node>();
			new loadDataRightMenu().execute();
			drawerListRight.setOnItemClickListener(new OnItemClickListener() {
				@Override
				public void onItemClick(AdapterView<?> arg0, View arg1,
						int position, long arg3) {
					Log.d("position", categoryList.get(position).getTitle());
					//
					Fragment fragment = new ForumNodeFragment();
					// pass parameter
					Bundle bundle = new Bundle();
					bundle.putString("nodeId", categoryList.get(position)
							.getNodeId());
					bundle.putInt("groupPosition", position);
					bundle.putInt("childPosition", 0);
					fragment.setArguments(bundle);
					// transaction
					FragmentTransaction transaction = getFragmentManager()
							.beginTransaction();

					transaction.replace(R.id.frame_container, fragment,
							"ThreadFragment");
					transaction.addToBackStack("replaceThreadFragment");
					transaction.commit();
					// update selected item and title, then close the drawer
					drawerExpandableListLeft.setItemChecked(position, true);
					drawerExpandableListLeft.setSelection(position);
					setTitle(categoryList.get(position).getTitle());
					drawerLayout.closeDrawer(drawerListRight);

				}
			});

			// on first time display view for first item
			if (savedInstanceState == null) {

				displayViewLeft(0);

			}
			// } else {
			// Fragment fragment = new ConnectionFragment();
			// Log.d("server state", "" + serverStatus);
			// Bundle bundle = new Bundle();
			// bundle.putInt("error", 2);
			// fragment.setArguments(bundle);
			// getFragmentManager().beginTransaction()
			// .replace(R.id.frame_container, fragment).commit();
			// }
		} else {
			Log.d("network state", " " + Global.networkStatus);
			Fragment fragment = new ConnectionFragment();
			Bundle bundle = new Bundle();
			bundle.putInt("error", 1);
			fragment.setArguments(bundle);
			getFragmentManager().beginTransaction()
					.replace(R.id.frame_container, fragment).commit();
		}

		// enable action bar app icon and behaving it as toggle button
		getActionBar().setDisplayHomeAsUpEnabled(true);
		getActionBar().setHomeButtonEnabled(true);
		drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
				R.drawable.ic_drawer, R.string.app_name, R.string.app_name) {
			@Override
			public void onDrawerClosed(View drawerView) {
				getActionBar().setTitle(title);
				// call onPrepareOptionsMenu() to show action bar icons
				invalidateOptionsMenu();
			}

			@Override
			public void onDrawerOpened(View drawerView) {
				getActionBar().setTitle(title);
				invalidateOptionsMenu();
			}
		};
		drawerLayout.setDrawerListener(drawerToggle);

	}

	@Override
	protected void onDestroy() {
		if (adView != null) {
			adView.destroy();
		}
		super.onDestroy();
	}

	class loadDataRightMenu extends AsyncTask<String, String, String> {
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			pDialog = new ProgressDialog(MainActivity.this);
			pDialog.setMessage("Loading...");
			pDialog.setIndeterminate(false);
			pDialog.setCancelable(false);
			pDialog.show();
		}

		@Override
		protected String doInBackground(String... arg0) {
			if (isCancelled()) {
				return null;
			}
			try {
				java.lang.Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
			JSONObject jsonRespond = jsonParser.makeHttpRequest(URL, "GET",
					params);
			if (jsonRespond != null) {
				try {
					JSONObject jsonNodes = jsonRespond.getJSONObject("nodes");
					Node node = null;
					SharedPreferences sp = PreferenceManager
							.getDefaultSharedPreferences(MainActivity.this);
					Editor editor = sp.edit();
					editor.putString("jsonNodes", jsonNodes.toString());
					// Log.d("jsonNodes", jsonNodes.toString());
					editor.commit();

					Iterator<?> keys = jsonNodes.keys();
					while (keys.hasNext()) {
						String key = (String) keys.next();
						JSONObject jsonNode = jsonNodes.getJSONObject(key);
						node = new Node();
						node.setNodeId(jsonNode.getString(TAG_NODE_ID));
						node.setTitle(jsonNode.getString(TAG_TITLE));
						node.setParentNodeId(jsonNode
								.getString(TAG_PARENT_NODE_ID));
						node.setDisplayOrder(jsonNode
								.getString(TAG_DISPLAY_ORDER));
						node.setDescription(jsonNode.getString(TAG_DESCRIPTION));
						node.setDisplayInList(jsonNode
								.getString(TAG_DISPLAY_IN_LIST));
						node.setDepth(jsonNode.getString(TAG_DEPTH));
						nodeList.add(node);
					}
					for (int i = 0; i < nodeList.size(); i++) {
						if (nodeList.get(i).getParentNodeId().equals("0")) {
							categoryList.add(nodeList.get(i));
						}
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			pDialog.dismiss();
			Collections.sort(categoryList, new Comparator<Node>() {
				@Override
				public int compare(Node lhs, Node rhs) {

					return lhs.getDisplayOrder().compareTo(
							rhs.getDisplayOrder());
				}
			});
			runOnUiThread(new Runnable() {
				public void run() {
					CustomNodeListAdapter adapter = new CustomNodeListAdapter(
							MainActivity.this, categoryList);
					drawerListRight.setAdapter(adapter);
				}
			});
		}
	}

	private void setDataLeftMenu() {
		// add main menu items
		listParentDataLeft.add(new NavDrawerItem(leftMenuTitle[0], 0, false));
		listParentDataLeft.add(new NavDrawerItem(leftMenuTitle[1], 0, false));
		listParentDataLeft.add(new NavDrawerItem(leftMenuTitle[2], leftMenuIcon
				.getResourceId(0, -1), true));
		listParentDataLeft.add(new NavDrawerItem(leftMenuTitle[3], 0, false));
		listParentDataLeft.add(new NavDrawerItem(leftMenuTitle[4], leftMenuIcon
				.getResourceId(2, -1), true));
		leftMenuIcon.recycle();
		// add child menu items
		ArrayList<NavDrawerItem> FrontpageList = new ArrayList<NavDrawerItem>();
		ArrayList<NavDrawerItem> TimelineList = new ArrayList<NavDrawerItem>();
		ArrayList<NavDrawerItem> AccountList = new ArrayList<NavDrawerItem>();
		// add account menu itesm
		for (int i = 0; i < accountTitles.length; i++) {
			AccountList.add(new NavDrawerItem(accountTitles[i], accountIcons
					.getResourceId(i, -1)));
		}

		ArrayList<NavDrawerItem> CasualList = new ArrayList<NavDrawerItem>();
		ArrayList<NavDrawerItem> SettingList = new ArrayList<NavDrawerItem>();
		// add setting menu itesm
		for (int i = 0; i < settingTitles.length; i++) {
			SettingList.add(new NavDrawerItem(settingTitles[i], settingIcons
					.getResourceId(i, -1)));
		}
		settingIcons.recycle();

		listChildDataLeft.put(listParentDataLeft.get(0), FrontpageList);
		listChildDataLeft.put(listParentDataLeft.get(1), TimelineList);
		listChildDataLeft.put(listParentDataLeft.get(2), AccountList);
		listChildDataLeft.put(listParentDataLeft.get(3), CasualList);
		listChildDataLeft.put(listParentDataLeft.get(4), SettingList);

		expListAdapterLeft = new ExpListAdapterLeft(MainActivity.this,
				listParentDataLeft, listChildDataLeft, getFragmentManager());
		expListAdapterLeft.notifyDataSetChanged();
		drawerExpandableListLeft.setAdapter(expListAdapterLeft);
	}

	private void displayViewLeft(int groupPosition) {
		Fragment fragment = null;
		switch (groupPosition) {
		case 0:
			fragment = new ThreadFragment();
			fragment.setArguments(passData(groupPosition, 0, ""));
			break;
		case 1:
			fragment = new ThreadFragment();
			fragment.setArguments(passData(groupPosition, 0, ""));
			break;
		case 3:
			fragment = new ThreadFragment();
			fragment.setArguments(passData(groupPosition, 0, ""));
			break;
		default:
			break;
		}

		if (fragment != null) {
			FragmentTransaction transaction = getFragmentManager()
					.beginTransaction();

			transaction.replace(R.id.frame_container, fragment,
					"ThreadFragment");
			transaction.addToBackStack("replaceThreadFragment");
			transaction.commit();
			// update selected item and title, then close the drawer
			drawerExpandableListLeft.setItemChecked(groupPosition, true);
			drawerExpandableListLeft.setSelection(groupPosition);
			setTitle(leftMenuTitle[groupPosition]);
			drawerLayout.closeDrawer(drawerExpandableListLeft);
		} else {
			Log.e("MainActivity", "Error in creating fragment");
		}
	}

	private void displayViewLeft(int groupPosition, int childPosition) {
		// Log.d("position", ">>> " + groupPosition + ">>> " + childPosition);
		Fragment fragment = null;
		switch (groupPosition) {
		case 0:
			fragment = new ThreadFragment();
			fragment.setArguments(passData(groupPosition, 0, ""));
			break;
		case 1:
			fragment = new ThreadFragment();
			fragment.setArguments(passData(groupPosition, 0, ""));
			break;

		case 2:
			switch (childPosition) {
			case 0:
				fragment = new GetUserFragment();
				fragment.setArguments(passData(groupPosition, childPosition, ""));

				break;
			case 1:
				fragment = new ThreadFragment();
				// passing data to fragments
				fragment.setArguments(passData(groupPosition, childPosition, ""));

				break;
			case 2:
				fragment = new ThreadFragment();
				fragment.setArguments(passData(groupPosition, childPosition, ""));

				break;
			case 3:
				fragment = new ThreadFragment();
				fragment.setArguments(passData(groupPosition, childPosition, ""));

				break;
			case 4:
				fragment = new ThreadFragment();
				fragment.setArguments(passData(groupPosition, childPosition, ""));

				break;

			}
			break;
		case 3:
			fragment = new ThreadFragment();
			fragment.setArguments(passData(groupPosition, 0, ""));
			break;
		case 4:
			break;

		default:
			break;
		}
		if (fragment != null) {
			FragmentTransaction transaction = getFragmentManager()
					.beginTransaction();
			transaction.replace(R.id.frame_container, fragment);
			transaction.addToBackStack("replaceThreadFragment");
			transaction.commit();
			// update selected item and title, then close the drawer
			drawerExpandableListLeft.setItemChecked(childPosition, true);
			drawerExpandableListLeft.setSelection(childPosition);
			setTitle(listChildDataLeft
					.get(listParentDataLeft.get(groupPosition))
					.get(childPosition).getTitle());
			drawerLayout.closeDrawer(drawerExpandableListLeft);
		} else {
			Log.e("MainActivity", "Error in creating fragment");
		}

	}

	public Bundle passData(int groupPosition, int childPosition, String nodeId) {
		Bundle bundle = new Bundle();
		bundle.putString("nodeId", nodeId);
		bundle.putInt("groupPosition", groupPosition);
		bundle.putInt("childPosition", childPosition);
		return bundle;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// toggle drawer on selecting action bar app icon/title
		if (drawerToggle.onOptionsItemSelected(item)) {
			if (drawerLayout.isDrawerVisible(drawerListRight)) {
				drawerLayout.closeDrawer(drawerListRight);
			}
			return false;
		}
		// handle action bar actions click
		switch (item.getItemId()) {
		case R.id.action_settings:
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}

	}

	// called when invalidate option menu is triggered
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// if drawer is open, hide the action items
		boolean drawerOpen = drawerLayout
				.isDrawerOpen(drawerExpandableListLeft);
		menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
		return super.onPrepareOptionsMenu(menu);
	}

	// set title action bar
	public void setTitle(CharSequence title) {
		this.title = title;
		getActionBar().setTitle(title);
	}

	/**
	 * When using the ActionBarDrawerToggle, you must call it during
	 * onPostCreate() and onConfigurationChanged()...
	 */
	@Override
	protected void onPostCreate(Bundle savedInstanceState) {

		super.onPostCreate(savedInstanceState);
		// sync the toggle state after onRestoreInstanceState has occurred
		drawerToggle.syncState();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {

		super.onConfigurationChanged(newConfig);
		// pass any configuration change to the drawer toggle
		drawerToggle.onConfigurationChanged(newConfig);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onForumNodeClick(String nodeId, boolean haveChild) {
		this.nodeId = nodeId;
		if (haveChild) {
			ForumChildNodeFragment forumChildNodeFragment = new ForumChildNodeFragment();
			forumChildNodeFragment.getChildNodeId(this.nodeId);
			FragmentTransaction transaction = getFragmentManager()
					.beginTransaction();
			transaction.replace(R.id.frame_container, forumChildNodeFragment);
			transaction.addToBackStack("replaceForumChildNodeFragment");
			transaction.commit();

		} else {
			ThreadFragment threadFragment = new ThreadFragment();
			threadFragment.getThreadId(this.nodeId);
			FragmentTransaction transaction = getFragmentManager()
					.beginTransaction();
			transaction.replace(R.id.frame_container, threadFragment);
			transaction.addToBackStack("replaceThreadFragment");
			transaction.commit();

		}

	}

	@Override
	public void onForumChildNodeClick(String nodeId, boolean haveChild) {
		this.nodeId = nodeId;

		if (haveChild) {
			ForumChildChildNodeFragment forumChildChildNodeFragment = new ForumChildChildNodeFragment();
			forumChildChildNodeFragment.getChildChildNodeId(this.nodeId);
			FragmentTransaction transaction = getFragmentManager()
					.beginTransaction();
			transaction.replace(R.id.frame_container,
					forumChildChildNodeFragment);
			transaction.addToBackStack("replaceForumChildChildNodeFragment");
			transaction.commit();

		} else {
			ThreadFragment threadFragment = new ThreadFragment();
			threadFragment.getThreadId(this.nodeId);
			FragmentTransaction transaction = getFragmentManager()
					.beginTransaction();
			transaction.replace(R.id.frame_container, threadFragment);
			transaction.addToBackStack("replaceForumChildFragment");
			transaction.commit();

		}

	}

	@Override
	public void onForumChildChildNodeClick(String nodeId, boolean haveChild) {
		this.nodeId = nodeId;
		ThreadFragment threadFragment = new ThreadFragment();
		threadFragment.getThreadId(this.nodeId);
		FragmentTransaction transaction = getFragmentManager()
				.beginTransaction();
		transaction.replace(R.id.frame_container, threadFragment);
		transaction.addToBackStack("replaceForumChildChildNodeFragment");
		transaction.commit();

	}

	@Override
	public void onThreadClick(String threadId) {
		this.threadId = threadId;
		PostFragment postFragment = new PostFragment();
		postFragment.getThreadId(this.threadId);
		//
		FragmentTransaction transaction = getFragmentManager()
				.beginTransaction();
		transaction.replace(R.id.frame_container, postFragment);
		transaction.addToBackStack("replaceThreadFragment");
		transaction.commit();

	}

}
